package thread;
/*同步块
有效的缩小范围可以在保证并发安全你的前提下尽可能提高开发效率

语法：
synchronzed（同步监视器对象）｛
   需要多线程同步执行的代码片段
｝
 */
public class SyncDemo02 {
    public static void main(String[] args) {
        shop shop = new shop();
        Thread t1 = new Thread("lilei"){
            @Override
            public void run(){
                shop.buy();
            }
        };
        Thread t2= new Thread("hanmei"){
            @Override
            public void run(){
                shop.buy();
            }
        };
        t1.start();
        t2.start();
    }
}
class  shop{
    /*在方法上直接使用synchronize时，同步监视器对象就是this，且不可选*/
    //public synchronized void buy(){
    public void buy(){
        try {
            Thread t1 = Thread.currentThread();
            System.out.println(t1.getName() + "看衣服");
            Thread.sleep(1000);
            /*使用同步块时需要指明同步监视器对象
            该对象必须满足的要求
            1、必须是引用类型
            2、要保证多个需要同步执行该代码片段的线程看到的是必须唯一（同一对象）

            合适的锁对象
            当多个线程发生争抢是，他们应当看到同一个锁对象
            当不发生争抢时，他们应该看到不同的锁对象

            因此，同步监视器对象（上锁的对象）选择
            通常可以选择临界资源（抢谁就锁谁）
             */
            //synchronized (new Object（）) {//不可以，多个线程看到的不是同一个对象
            //synchronized ("this") {//字符串，，这个可以，但是不是合适的锁对象，
            //因为String的对象是惟一的，一旦被创建，就不会改变，用这个对象来锁的话，后续场景中不管抢的是不是同一个资源，都会进行上锁，造成资源浪费

            synchronized (this) {
                System.out.println(t1.getName() + "试衣服");
                Thread.sleep(1000);
            }
            System.out.println(t1.getName() +"买衣服");
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}